home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 October: Mac OS SDK / Dev.CD Oct 96 SDK / Dev.CD Oct 96 SDK2.toast / Development Kits (Disc 2) / OpenDoc Development Framework / Documentation / Engineering Notes / Foundation / Notification next >
Encoding:
Text File  |  1996-08-16  |  9.5 KB  |  147 lines  |  [TEXT/ttxt]

  1. OpenDoc
  2. Development
  3. Framework
  4.                                                                                                                                                                                     
  5. Notification
  6. ODF Release 1                                                                                                                                                             
  7.  
  8. The Notification subsystem was inspired by Taligent's Notification framework. It is a lighter implementation that covers ODF needs without adding too much complexity (see "Inside Taligent Technology", AddisonWesley, page 202 and 328).
  9.  
  10. The Notification subsystem defines a mechanism for sending synchronous messages within your part.  It allows any number of client objects to react to a particular event or  maintain a consistent state with respect to a particular source.  Notifications are different from regular events or scripting events sent by the operating system, in that they are immediate and do not go through your part's event dispatchers.
  11.  
  12. ODF uses notifications mainly in conjunction with the Views subsystem to send messages from some view objects to other view objects in response to specific UI events (for more information see the Engineering notes on various view classes). You can use notifications for the same purpose in your part's user interface or for  other purposes which fit the architecture.
  13.  
  14. The 4 elements of the notification mechanism are:
  15.  
  16. NOTIFIERS (class FW_MNotifier): notifiers are objects that notify other objects of changes to themselves; the notifier defines an interest that's specific to the notification for a particular kind of change. For instance an FW_CButton instance notifies other objects when a mouse click occurred and changed its state.
  17.  
  18. RECEIVERS  (class FW_MReceiver): receivers register interests in and respond to notifications from notifiers when they are connected.  For example a FW_CFrame instance registers an interest to be notified when a click occurs in a button.
  19.  
  20. INTERESTS  (class FW_CInterest):  Interests identify a notifier and an event.  A notifier defines an interest in each event about which it provides notification.  A receiver uses this protocol to identify the events about which it should be notified.  There is no direct link between the receiver and the notifier; the interest object isolates the source (the notifier) from the details of its clients (the receivers).  The interest composed of a FW_CButton instance and the FW_kButtonPressedMsg message identifies a mouse click in this button.
  21.  
  22. NOTIFICATIONS  (class FW_CNotification): notifications are messaging objects, they convey news of an event from a notifier to one or more receivers.  When a notifier receives an event for which it has defined an interest, it uses the
  23. appropriate interest, and possibly additional notification-specific data, to create a notification and sends it to the receivers that want it.  For example, in response to a mouse click, an FW_CButton instance creates a FW_CControlNotification made of the "click" interest and a reference to the control itself.
  24.  
  25. FW_MReceiver and FW_MNotifier classes are used as mixins with other classes.  FW_CNotification can be subclassed to include additional information.   FW_CInterest cannot be subclassed in the current version.
  26.  
  27. Notes: 
  28.  
  29. • FW_MNotifier and FW_MReceiver are similar to the LBroadcaster and LListener classes in Metrowerk's PowerPlant. 
  30.  
  31. • Inter-part communications cannot be handled with notifications in the current version, you must use scripting, linking or extensions.
  32.  
  33.  
  34. FW_CInterest
  35.  
  36. The FW_CInterest class defines an interest as an event's message value and a notifier.  Reserved ODF messages have negative values and are defined in FWNotDef.h.  Use positive values for your custom messages.
  37.  
  38. Usually you will create FW_CInterest objects in 2 places:
  39.  
  40. 1) To register the interest to a receiver:
  41.  
  42.   myReceiver->AddInterest(FW_CInterest(myNotifier, myMessage));
  43.  
  44. 2) To create a notification for that interest before sending it:
  45.   
  46.   FW_CNotification  myNotification(FW_CInterest((myNotifier, myMessage));
  47.   myNotifier->Notify(ev, myNotification);
  48.  
  49. You can also avoid dealing with FW_CInterest by using the following  API in place of AddInterest:
  50.  
  51.   myReceiver->AddNotifier(myNotifier, myMessage);
  52.  
  53. If you feel the need to include additional information to refine the interest specification you must subclass  FW_CNotification.  
  54.  
  55.  
  56. FW_CNotification
  57.  
  58. FW_CNotification is the base class for transporting notification-specific information.  It contains an FW_CInterest specifying the sender and the event about which the notification is generated.
  59.  
  60. Typically the notifier will respond to an event with the following code:
  61.  
  62.   FW_CNotification  myNotification(FW_CInterest((myNotifier, myMessage));
  63.   myNotifier->Notify(ev, myNotification);
  64.  
  65. This will send the notification instance to each receiver which is connected and which has registered the same interest.  In turn a receiver will respond to the notification in its HandleNotification() method.  In general a receiver can process several kinds of notifications, so it's common to do a switch on the type of message carried by the notification:
  66.  
  67. void  MyReceiverClass::HandleNotification(Environment* ev, const
  68. FW_CNotification& notification)
  69. {
  70.      switch(notification.GetMessage())
  71.   {
  72.    case valueA:
  73.       FW_CNotifier* notifier = notification.GetNotifier();
  74.       <etc.>
  75.       break;
  76.  
  77.    case valueB:
  78.       <etc.>
  79.   }
  80. }
  81.  
  82. FW_CNotification can be subclassed to add additional information that you want to be carried along to the receivers.  This way your HandleNotification method can access more specific information instead of relying only on the FW_CNotifier pointer as shown above.
  83.  
  84. ODF derives several classes to handle notifications on certain kind of views:  FW_CControlNotification, FW_CPopupMenuNotification, FW_CScrollNotification and FW_CListBoxNotification.  For instance a mouse click in a button will send an FW_CControlNotification from which you can get the FW_CControl object and view id.  By default an FW_CControlNotification contains the message FW_kButtonPressedMsg (unless you have defined a custom message for your control view) so you can safely downcast the FW_CNotification argument when you handle this message:
  85.  
  86. void  MyFrameClass::HandleNotification(Environment* ev, const
  87. FW_CNotification& notification)
  88. {
  89.      switch(notification.GetMessage())
  90.   {
  91.    case FW_kButtonPressedMsg:
  92.       // Safe cast to FW_CControlNotification
  93.       FW_CControlNotification& controlNotification =
  94.                                      (FW_CControlNotification&)notification;
  95.  
  96.       // Now we can get the control or the view id
  97.       FW_CControl* control = controlNotification.GetControl(ev);
  98.       ODID viewId = controlNotification.GetViewId(ev);
  99.  
  100.          <etc.>
  101.       break;
  102.   ...
  103.  
  104. Note: FW_CNotification classes also support the ODF RTTI macro FW_DYNAMIC_CAST if needed.
  105.  
  106.  
  107. FW_MNotifier
  108.  
  109. FW_MNotifier is a class generally used as a mixin with other classes to give objects the power of sending notifications in response to events.  The current ODF classes derived from FW_MNotifier are all views (controls, edit view, list box) which react to UI events such as mouse clicks, scrolling and double-click.
  110.  
  111. After making your class derive from FW_MNotifier all you need to do is use the Notify() method to send the notification of your choice.
  112.  
  113.   FW_CNotification  myNotification(FW_CInterest(myNotifier, myMessage));
  114.   myNotifier->Notify(ev, myNotification);
  115.  
  116. This notification will be received by all the objects which are connected to this notifier and have registered the same interest.
  117.  
  118. When a notifier object is deleted it sends a notification with the message FW_kNotifierDeletedMsg to its receivers.  This is used by FW_CRadioCluster to delete itself after all radio buttons have been removed. You can use it for your own purposes. The destructor of FW_CNotifier also removes the appropriate interests from its receivers.
  119.  
  120.  
  121. FW_MReceiver
  122.  
  123. FW_MReceiver is a class generally used as a mixin with other classes to give objects the ability to respond to  notifications.  The current ODF classes deriving from FW_MReceiver are FW_CRadioCluster (to handle a group of radio buttons), FW_CScroller (to scroll in response to mouse clicks in scrollbar controls) and FW_CDialogFrame (to respond to OK/Cancel buttons and other controls).
  124.  
  125. After making your class derive from FW_MReceiver there are 2 basic steps to be able to handle notifications:
  126.  
  127. 1) Decide which interests your class should register to.  A receiver can process notifications from more than one source.  Make calls to AddInterest or use the AddNotifier inline.
  128.  
  129.   myReceiver->AddInterest(FW_CInterest(myNotifier, myMessage));
  130. or
  131.   myReceiver->AddNotifier(myNotifier, myMessage);
  132.  
  133. If the receiver is linked to controls you can also use the following FW_CControl method
  134.  
  135.   myControl->LinkControlTo(ev, myReceiver);
  136.  
  137. or you can simply define the control's receiver in resources.
  138.  
  139. 2) Override the HandleNotification method (see sample code above).
  140.  
  141. A receiver is connected automatically when it is created.  It can be disconnected temporarily with Disconnect(), i.e. it stops receiving any notification, and reconnected with Connect().  You can also remove a specific interest with RemoveInterest() and remove all interests permanently with RemoveAllInterests().   
  142.  
  143. Note: You should not remove interests in the destructor of your receiver class, it is already handled by FW_MReceiver.
  144.  
  145.  
  146. © 1993 - 1996 Apple Computer, Inc. All rights reserved.
  147. Apple, the Apple Logo, Macintosh, and OpenDoc are trademarks of Apple Computer, Inc., registered in the United States and other countries.